package com.fiberhome.opticalbox.ui.fragment;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;


import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.fiberhome.opticalbox.R;
import com.fiberhome.airplay.HttpServer;
import com.fiberhome.airplay.HttpServer.DownloadListener;
import com.fiberhome.airplay.jmdns.ServiceInfo;
import com.fiberhome.opticalbox.App;
import com.fiberhome.opticalbox.BaseFragment;
import com.fiberhome.opticalbox.C;
import com.fiberhome.opticalbox.common.FileSearchService;
import com.fiberhome.opticalbox.ui.PutVideoActivity;
import com.fiberhome.opticalbox.utils.ImageUtil;
import com.fiberhome.opticalbox.utils.ScreenUtil;

public class TvProjectionVideoFragment extends BaseFragment {

	private ListView listView;
	private List<File> fileList = new ArrayList<File>();

	private Bitmap defaultBitmapHolder;

	private HttpServer http = new HttpServer();

	@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.ob_fragment_tv_projection_video, null);
		listView = (ListView) view.findViewById(R.id.ob_listView);
		listView.setAdapter(adapter);
		listView.setOnItemClickListener(new OnItemClickListener() {
			@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				ServiceInfo serviceInfo = TvProjectionFragment.getSelectedServiceInfo();
				if (serviceInfo == null) {
					TvProjectionFragment tpFragment = (TvProjectionFragment) getParentFragment();
					tpFragment.animTitleInfoShake();
				} else {
					actionStart(PutVideoActivity.class, C.bundle.videoPosition, position);
				}
			}
		});

		http.startServer(9999);
		http.setDownloadListener(new DownloadListener() {
			@Override public void onFileSendFinished() {
				handler.post(new Runnable() {
					@Override public void run() {
						showToast("httpServer onFileSendFinished");
					}
				});
			}
		});

		bindFileSearchService();
		registerFileSearchReceiver();

		return view;
	}

	@Override public void onDestroy() {
		super.onDestroy();
		
		http.stopServer();
		
		unBindFileSearchService();
		unregisterFileSearchReceiver();
	}

	private void bindFileSearchService() {
		if (holder != null) {
			Intent intent = new Intent(holder, FileSearchService.class);
			holder.bindService(intent, mServiceConnection, Activity.BIND_AUTO_CREATE);
		}
	}

	private void unBindFileSearchService() {
		if (holder != null) {
			holder.unbindService(mServiceConnection);
		}
	}

	private final ServiceConnection mServiceConnection = new ServiceConnection() {
		@Override public void onServiceConnected(ComponentName componentName, IBinder service) {
			FileSearchService fileSearchService = ((FileSearchService.LocalBinder) service).getService();
			fileList = fileSearchService.getVedioList();
			adapter.notifyDataSetChanged();
		}

		@Override public void onServiceDisconnected(ComponentName componentName) {
		}
	};

	private void registerFileSearchReceiver() {
		if (holder != null) {
			IntentFilter intentFilter = new IntentFilter();
			intentFilter.addAction(FileSearchService.ACTION_SEARCHED_VIDEO);
			holder.registerReceiver(fileSearchReceiver, intentFilter);
		}
	}

	private void unregisterFileSearchReceiver() {
		if (holder != null) {
			holder.unregisterReceiver(fileSearchReceiver);
		}
	}

	private final BroadcastReceiver fileSearchReceiver = new BroadcastReceiver() {
		@Override public void onReceive(Context context, Intent intent) {
			final String action = intent.getAction();
			if (FileSearchService.ACTION_SEARCHED_VIDEO.equals(action)) {
				adapter.notifyDataSetChanged();
			}
		}
	};

	public BaseAdapter adapter = new BaseAdapter() {

		@Override public int getCount() {
			return fileList.size();
		}

		@Override public Object getItem(int position) {
			return fileList.get(position);
		}

		@Override public long getItemId(int position) {
			return position;
		}

		@Override public View getView(int position, View convertView, ViewGroup parent) {
			File file = fileList.get(position);
			ViewHolder viewHolder;
			if (convertView != null) {
				viewHolder = (ViewHolder) convertView.getTag();
			} else {
				viewHolder = new ViewHolder();

				convertView = LayoutInflater.from(holder).inflate(R.layout.ob_list_content_tv_projection_video, null);
				viewHolder.imageView = (ImageView) convertView.findViewById(R.id.ob_imageView);
				viewHolder.txPath = (TextView) convertView.findViewById(R.id.tx_path);
				viewHolder.txTime = (TextView) convertView.findViewById(R.id.tx_time);

				LayoutParams para = viewHolder.imageView.getLayoutParams();
				para.height = ScreenUtil.getScreenHeight(holder) / 6;
				viewHolder.imageView.setLayoutParams(para);

				convertView.setTag(viewHolder);
			}

			if (holder != null) {
				if (defaultBitmapHolder == null) {
					defaultBitmapHolder = ImageUtil.decodeResource(holder.getResources(), R.drawable.ob_tv_video_default,
							viewHolder.imageView.getWidth(), viewHolder.imageView.getHeight());
				}
				viewHolder.imageView.setImageBitmap(defaultBitmapHolder);
				setImageBitmapForCover(Uri.fromFile(file), viewHolder.imageView);

			}

			viewHolder.txPath.setText(file.getName());

			String sizeInfo = "";
			if (file.length() < 1024) {
				sizeInfo = file.length() + "b";
			} else if (file.length() < 1024 * 1024) {
				sizeInfo = (int) (file.length() / 1024f) + " kb";
			} else {
				sizeInfo = String.format("%.2f", (file.length() / (1024f * 1024))) + " mb";
			}

			viewHolder.txTime.setText(getString(R.string.ob_file_size) + sizeInfo);

			return convertView;
		}

		class ViewHolder {
			ImageView imageView;
			TextView txPath, txTime;
		}
	};

	private void setImageBitmapForCover(final Uri uri, final ImageView imageView) {
		new Thread(new Runnable() {
			@Override public void run() {
				if (holder != null) {
					final Bitmap bitmap = createVideoThumbnail(holder, uri, imageView.getWidth(), imageView.getHeight());
					holder.runOnUiThread(new Runnable() {
						@Override public void run() {
							imageView.setImageBitmap(bitmap);
						}
					});
				}
			}
		}).start();
	}

	private Bitmap createVideoThumbnail(Context context, Uri uri, int reqWidth, int reqHeight) {

		Bitmap bitmap = App.i().bitmapCache.getBitmap(uri.getPath());

		if (bitmap != null) {
			return bitmap;
		}

		String className = "android.media.MediaMetadataRetriever";
		Object objectMediaMetadataRetriever = null;
		Method release = null;
		try {
			objectMediaMetadataRetriever = Class.forName(className).newInstance();
			Method setDataSourceMethod = Class.forName(className).getMethod("setDataSource", Context.class, Uri.class);
			setDataSourceMethod.invoke(objectMediaMetadataRetriever, context, uri);
			Method getFrameAtTimeMethod = Class.forName(className).getMethod("getFrameAtTime");
			bitmap = (Bitmap) getFrameAtTimeMethod.invoke(objectMediaMetadataRetriever);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (release != null) {
					release.invoke(objectMediaMetadataRetriever);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		if (bitmap == null) {
			bitmap = ImageUtil.decodeResource(holder.getResources(), R.drawable.ob_tv_video_default, reqWidth, reqHeight);
		}

		App.i().bitmapCache.putBitmap(uri.getPath(), bitmap);

		return bitmap;
	}

}
